//
//  DatabaseManager.m
//  LBBase
//
//  Created by Gary on 15/7/1.
//  Copyright (c) 2015年 Lebo. All rights reserved.
//

#import "DatabaseManager.h"
#import "FMDBManager.h"
#import "CommonDefine.h"
#import "Common.h"

@implementation DatabaseManager {
    FMDBManager *_manager;
}

- (instancetype)init {
    if (self = [super init]) {
        self.moduleID = EDatabaseManager;
        _manager = [FMDBManager sharedInstance];
    }
    return self;
}

#pragma mark - 执行sql

- (BOOL)executeSqlSync:(NSString*)sql {
    if (![Common isEmptyString:sql]) {
        return [_manager executeUpdate:sql];
    }
    return NO;
}

- (void)executeSqlAsync:(NSString*)sql {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL result = [self executeSqlSync:sql];
        dispatch_async(dispatch_get_main_queue(), ^{
            [BF broadcastBusinessNotification:BusinesID(EDatabaseManager, EDBInsertAsync)
                                      inParam:[NSNumber numberWithBool:result]];
            LogInfo(@"executeSqlAsync has finished!");
        });
    });
}

- (BOOL)executeSqlBatchSync:(NSArray*)sqls {
    if (sqls) {
        return [_manager executeUpdate:sqls values:nil isTransaction:YES];
    }
    return NO;
}

- (void)executeSqlBatchAsync:(NSArray*)sqls {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL result = [self executeSqlBatchSync:sqls];
        dispatch_async(dispatch_get_main_queue(), ^{
            [BF broadcastBusinessNotification:BusinesID(EDatabaseManager, EDBInsertAsync)
                                      inParam:[NSNumber numberWithBool:result]];
            LogInfo(@"executeSqlAsync has finished!");
        });
    });
}

#pragma mark - 执行查询的sql

- (NSArray*)selectRecordAll:(BaseModel*)model {
    if (model) {
        NSString *sql = [NSString stringWithFormat:@"select * from %@", [model.class tableName]];
        return [_manager executeQuery:sql class:model.class];
    }
    return nil;
}

- (NSArray*)selectRecord:(NSDictionary*)dic {
    BaseModel *model = [dic objectForKey:kDBModelKey];
    NSString *sql = [dic objectForKey:kDBSqlKey];
    if (model) {
        if ([Common isEmptyString:sql]) {
            return [self selectRecordAll:model];
        } else {
            return [_manager executeQuery:sql class:model.class];
        }
    }
    return nil;
}

#pragma mark - 添加数据

- (BOOL)insertSync:(BaseModel*)model {
    if (model) {
        return [_manager insert:model];
    }
    return NO;
}

- (void)insertAsync:(BaseModel*)model {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL result = [self insertSync:model];
        dispatch_async(dispatch_get_main_queue(), ^{
            [BF broadcastBusinessNotification:BusinesID(EDatabaseManager, EDBInsertAsync)
                                      inParam:[NSNumber numberWithBool:result]];
            LogInfo(@"addAsync has finished!");
        });
    });
}

- (BOOL)insertBatchSync:(NSArray*)models {
    if (models) {
        return [_manager insert:models isTransaction:YES];
    }
    return NO;
}

- (void)insertBatchAsync:(NSArray*)models {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL result = [self insertBatchSync:models];
        dispatch_async(dispatch_get_main_queue(), ^{
            [BF broadcastBusinessNotification:BusinesID(EDatabaseManager, EDBInsertBatchAsync)
                                      inParam:[NSNumber numberWithBool:result]];
            LogInfo(@"addAllAsync has finished!");
        });
    });
}

#pragma mark - 删除数据

- (BOOL)deleteSync:(BaseModel*)model {
    if (model) {
        return [_manager deleteT:model];
    }
    return NO;
}

- (void)deleteAsync:(BaseModel*)model {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL result = [self deleteSync:model];
        dispatch_async(dispatch_get_main_queue(), ^{
            [BF broadcastBusinessNotification:BusinesID(EDatabaseManager, EDBDeleteAsync)
                                      inParam:[NSNumber numberWithBool:result]];
            LogInfo(@"deleteAsync has finished!");
        });
    });
}

#pragma mark - Business Delegate Methods

- (int)callBusinessFunc:(NSUInteger)funcID inParam:(id)inParam outParam:(id*)outParam {
    switch (funcID) {
        case EDBExecute: {
            *outParam = [NSNumber numberWithBool:[self executeSqlSync:inParam]];
            break;
        }
            
        case EDBExecuteAsync: {
            [self executeSqlAsync:inParam];
            break;
        }
            
        case EDBExecuteBatch: {
            *outParam = [NSNumber numberWithBool:[self executeSqlBatchSync:inParam]];
            break;
        }
            
        case EDBExecuteBatchAsync: {
            [self executeSqlBatchAsync:inParam];
            break;
        }
            
        case EDBSelect: {
            *outParam = [self selectRecord:inParam];
            break;
        }
            
        case EDBSelectAll: {
            *outParam = [self selectRecordAll:inParam];
            break;
        }
            
        case EDBInsert: {
            *outParam = [NSNumber numberWithBool:[self insertSync:inParam]];
            break;
        }
            
        case EDBInsertAsync: {
            [self insertAsync:inParam];
            break;
        }
            
        case EDBInsertBatch: {
            *outParam = [NSNumber numberWithBool:[self insertBatchSync:inParam]];
            break;
        }
            
        case EDBInsertBatchAsync: {
            [self insertBatchAsync:inParam];
            break;
        }
            
        case EDBDelete: {
            *outParam = [NSNumber numberWithBool:[self deleteSync:inParam]];
            break;
        }
            
        case EDBDeleteAsync: {
            [self deleteAsync:inParam];
            break;
        }
            
        default:
            LogError(@"DatabaseManager error with id:%ld", (unsigned long)funcID);
            break;
    }
    
    return 0;
}

- (void)dealloc {
    _manager = nil;
}

@end
